package be.novelfaces.webdriver;

import static be.novelfaces.showcase.webdriver.festassert.SourcePanelAssert.assertThat;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Collection;

import org.apache.commons.io.FileUtils;
import org.joda.time.DateTime;
import org.junit.Rule;
import org.junit.rules.TestWatchman;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.model.FrameworkMethod;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;

import be.novelfaces.component.webdriver.SourcePanel;
import be.novelfaces.showcase.webdriver.util.Browser;
import be.novelfaces.showcase.webdriver.util.ResourceBundleManager;

@RunWith(Parameterized.class)
public abstract class AbstractWebdriverTestCase {

	private static final String BUILD_INDENTIFIER = "Build_"
			+ new DateTime().toString("yyyyMMdd_HHmmss");

	@Rule
	public TestWatchman testWatchman = new TestWatchman() {
		@Override
		public void failed(Throwable e, FrameworkMethod method) {
			final String testOutputDirectory = "./target";
			WebDriver webdriver = WebDriverManager.getWebdriver();

			TakesScreenshot takesScreenshot = (TakesScreenshot) webdriver;
			String pageSource = webdriver.getPageSource();

			File screenshotAs = takesScreenshot
					.getScreenshotAs(OutputType.FILE);

			String path = testOutputDirectory + "/failed-webdriver-tests" + "/"
					+ BUILD_INDENTIFIER + "/"
					+ method.getMethod().getDeclaringClass().getSimpleName()
					+ "_" + method.getMethod().getName() + "/";

			try {
				FileUtils.copyFile(screenshotAs, new File(path
						+ "screenshot.png"));
				FileUtils.writeStringToFile(new File(path + "source.html"),
						pageSource);
				e.printStackTrace(new PrintStream(new File(path + "trace.txt")));
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}

	};

	public AbstractWebdriverTestCase(Browser browser) {
		WebDriverManager.initWebDriver(browser);
		String basePath = System.getProperty("profile") != null ? ""
				: "/novelfaces-showcase";
		WebDriverManager.getWebdriver().get(
				"http://localhost:8080" + basePath + "/");
	}

	@Parameters
	public static Collection<Object[]> data() {
		Object[][] data = new Object[][] { { Browser.FIREFOX } };
		return Arrays.asList(data);
	}

	protected WebDriver getWebDriver() {
		return WebDriverManager.getWebdriver();
	}

	protected void assertSourcePanel(SourcePanel sourcePanel, String headerKey,
			String contentToContain) {
		assertThat(sourcePanel).isRendered().isCollapsed(true)
				.hasHeader(getProperty(headerKey));
		sourcePanel.toggle();
		assertThat(sourcePanel).isCollapsed(false).containsContent(
				contentToContain);
	}

	public String getProperty(String key) {
		return ResourceBundleManager.getResourceBundle().getProperty(key);
	}

}
